Skip to content

feat: enforce OpenCode subagent permission constraints - #1921

Merged
limityan merged 2 commits into
GCWing:mainfrom
limityan:yanzhn/opencode-subagent-permissions
Jul 31, 2026
Merged

feat: enforce OpenCode subagent permission constraints#1921
limityan merged 2 commits into
GCWing:mainfrom
limityan:yanzhn/opencode-subagent-permissions

Conversation

@limityan

@limityan limityan commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

结果

为 OpenCode 外部 Subagent 接入可执行的 Agent-local 权限约束,同时保持 BitFun 现有权限管线为唯一最终裁决者。外部规则作为独立 constraint layer 参与裁决,只能收紧宿主策略,不能借 allow 扩大工具能力或绕过父级限制。

本 PR 约 2.4k 行变更,不新增运行时 owner,也不涉及 Plugin Host Runtime。

范围

  • 兼容当前生产 OpenCode V1 agent/prompt/disable/permission,并解析 Core V2 agents/system/disabled/permissions 的已验证安全子集。
  • 按单份 JSON/JSONC 与 Agent Markdown frontmatter 判型和迁移,避免跨文档误判 schema。
  • 支持 V1 精确 action map;将 write/edit/patch/apply_patch 归一为 BitFun edit,不猜测 action pattern 或嵌套 resource map。
  • 对齐生产来源阶段:用户 JSON/JSONC、OPENCODE_CONFIG、project direct config(root-to-nearest),再到用户 Agent Markdown、project .opencode config/Markdown(opened-to-root)、兼容用户目录和显式目录。
  • 物理目录 alias 保留首次出现的位置,只更新 scope/loading semantics。
  • 将 Core V2 相对 read/edit resource 按 active/opened Location 转成 BitFun 使用的 canonical workspace 坐标;只对路径类 action 展开 home,保留 bash 原始命令资源。
  • Windows action/resource 匹配保持大小写不敏感;跨内部相对路径与外部绝对路径域的歧义模式失败关闭。
  • 将约束通过 Agent registry、round execution 与 tool options 传入现有 Tool Pipeline,并纳入行为审批摘要。
  • 显式阻止受约束外部 Agent 使用 Task,避免当前子任务父级 ceiling 尚未携带外部约束时形成委派逃逸。
  • 加入 oh-my-openagent Oracle 旧版精确权限映射兼容夹具。

CI 修正

旧 head 的 Linux、macOS、Windows Rust job 均失败于相同两项 Core 来源顺序回归,不是平台差异:project .opencode 被错误按 root-to-nearest 应用,导致 nearest/inner 定义覆盖 outer 定义。

本次修正恢复生产 OpenCode 的两阶段顺序,并补齐生命周期语义:

  • project direct config:root-to-nearest;
  • .opencode 目录阶段:opened-to-root;
  • V1 disable:普通 deep-merge 字段,后续省略时保持禁用,显式 false 才重新启用;
  • Core V2 disabled:true:逐文档 tombstone;后续任意同名非 disabled contribution 从空定义重建;
  • mixed V2 tombstone → V1 re-add → V2 overlay 保留 V1 权限约束,不发生 deny 丢失。

设计取舍

主题 上游行为 本 PR 选择
权限规则 生产 V1 使用 action map;Core V2 使用 ordered rules Adapter 分别保留语义;Core 跨层取最严格结果
多来源 direct files 与目录阶段采用不同遍历顺序 Subagent provider 维护自身顺序,不强迫 Command/MCP 共享通用顺序
禁用语义 V1 deep-merge;Core V2 remove/re-add 逐文档标记 tombstone 能力,不把 V1 disable 误当删除
资源坐标 Core V2 相对 active Location 解释文件资源 Adapter 归一到 Tool Pipeline 使用的 canonical workspace 坐标
宿主边界 OpenCode 规则可决定其自身运行时 BitFun 外部规则不是第二权限 owner,只能约束现有宿主策略

竞品对照锁定到 OpenCode da59457ca4ff55aca0147d4ddb33c495dc72be31 的生产 V1 config owner、Core V2 config/location 实现,以及 oh-my-openagent Oracle 配置。

明确不做

  • 不实现或设计 Plugin Host Runtime。
  • 不激活 root ambient permission。
  • 不支持 V1 action pattern、嵌套 resource map 或跨路径域歧义 pattern。
  • 不开放受约束外部 Agent 的 Task 委派;后续只有在子任务 ceiling 能完整携带约束时才可单独评估。
  • 不用外部 allow 自动授予工具;工具资格与权限裁决保持分离。

验证

  • cargo test --locked -p bitfun-opencode-adapter --test opencode_subagent_adapter:20/20
  • cargo test --locked -p bitfun-core --lib:1680 passed、0 failed、1 ignored
  • cargo check -p bitfun-core --no-default-features --features product-full:通过
  • node scripts/check-core-boundaries.mjs:通过
  • pnpm run check:repo-hygiene:通过
  • git diff gcwing/main --check:通过

完整 cargo check --workspace 在本地仍受仓库未提供 src/mobile-web/dist 的 desktop embed 输入限制;未生成或提交无关前端产物。GitHub Actions run 30610811432 已在 exact head 11a0b4e505f03b622d6b2d5108f4814ff1b2a3d7 完成:Shell、Frontend、Ubuntu/macOS CLI 与 Ubuntu/Windows/macOS Rust 共 7/7 jobs 通过。

复审

独立对抗性复审覆盖生产来源顺序、alias/watch、V1/V2 disable/tombstone、mixed-schema 重建、资源坐标、Windows 匹配和委派逃逸。复审新增的 mixed-schema P1 已按失败回归修复;最终未发现遗留 P0/P1。

limityan added 2 commits July 31, 2026 14:47
Translate supported OpenCode agent permission rules into independent constraint layers and carry them through the existing tool pipeline. Preserve current source ordering, V1 migration, path semantics, and fail-closed behavior without adding a new runtime owner.
Restore upstream direct and directory source ordering. Keep V1 disable as a deep-merged field while preserving V2 tombstone and mixed-schema re-add behavior.
@limityan
limityan force-pushed the yanzhn/opencode-subagent-permissions branch from 5997f69 to 11a0b4e Compare July 31, 2026 06:49
@limityan
limityan merged commit f769918 into GCWing:main Jul 31, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant